import { table } from "../../api";
import { ValueReader } from "./value";
import { AreaReader } from "./area";
import { transformFilterData } from "@tablra/search/searchDefaults"
// import { handleArea } from '@basic/area/area'

import Vue from "vue";

const debug = process.env.NODE_ENV !== "production";

class TableColumn {
  constructor(column, columnMap) {
    Object.assign(this, column);
    let { type, group, name } = column;
    if (type === "dictionary") {
      this.type = "select";
      this.reader = (record) => {
        let value = record[name];
        return new ValueReader(group)[value]?.label;
      };
    } else if (this.type === "area") {
      this.type = "select";
      this.reader = (record) => {
        let value = record[name];
        return new AreaReader(name, value).label;
      };
    } else if (this.type === "object") {
      this.reader = (record) => {
        let value = record[name];
        return JSON.stringify(value);
      };
    }
    if (name) {
      columnMap[name] = column;
    }
  }
}

class TableColumns extends Array {
  constructor(columns) {
    super();
    this.columnMap = {};
    this.addColumns(columns);
  }

  addColumn (column) {
    this.push(new TableColumn(column, this.columnMap));
  }

  addColumns (columns) {
    columns
      .filter(column => !!column)
      .filter((column) => !column.hidden)
      .sort((a, b) => a.sort - b.sort)
      .forEach(column => this.addColumn(column));
  }
}

class TableFilter {
  constructor(filter, filterMap) {
    Object.assign(this, filter);
    filterMap[filter.name] = this;
  }
}

class TableFilters extends Array {
  constructor(filters, search) {
    super();
    this.filterMap = {};
    this.addFilters(filters);
    this.search = search;
  }

  addFilters (filters) {
    // console.log("Add filters:", JSON.stringify(filters));
    filters
      .filter(filter => !!filter)
      .filter((filter) => !filter.hidden)
      .sort((a, b) => a.sort - b.sort)
      .forEach(filter => this.addFilter(filter));
  }

  addFilter (filter) {
    this.push(new TableFilter(filter, this.filterMap));
  }
}


class DataResolver {
  constructor(data, filter) {
    const filterMap = filter.filterMap;
    for (const [name, value] of Object.entries(data)) {
      this[name] = value;
      if (value) {
        let filter = filterMap[name];
        if (filter?.type === "daterange") {
          this.handleDateRange(name, value, filter);
        } else if (filter?.type === "date") {
          this.handleDate(name, value);
        } else if (filter?.type === "area") {
          // handleArea({ key: name, value, _this: this });
        } else if (filter?.type === "rangeinput") {
          // this.handleRangeInput(name, value, filter);
        } else if (filter?.control === "all-levels") {
          this.handleAllLevels(name, value, filter);
        } else if (filter?.control === "sign") {
          this.handleSign(name, value, filter);
        } else if (filter?.control === "signs") {
          this.handleSigns(name, value, filter);
        } else if (filter?.name === "dateInterval") {
          this.handleRange(name, value, 2);
        } else if (filter?.name === "month") {
          this.handleRange(name, value, 1);
        } else if (filter?.name === "year") {
          this.handleYear(name, value);
        }
      }
    }
  }
  handleDateRange (key, value, filter) {
    // let beginValue = value?.[0];
    // if (beginValue instanceof Date) {
    //   beginValue = beginValue.format("yyyy-MM-dd 00:00:00");
    // }
    // let endValue = value?.[1];
    // if (endValue instanceof Date) {
    //   endValue = endValue.format("yyyy-MM-dd 23:59:59");
    // }
    // let [beginName, endName] = filter.keys || [key + "Begin", key + "End"];
    // this[beginName] = beginValue;
    // this[endName] = endValue;
  }
  handleDate (key, value) {
    if (value instanceof Date) {
      this[key] = value?.format("yyyy-MM-dd hh:mm:ss");
    }
  }

  handleRange (key, value, type) {
    let queryStartTime, queryEndTime;
    if (value) {
      queryStartTime = (value?.[0]).format(type == 1 ? "yyyyMM" : "yyyy-MM-dd");
      queryEndTime = (value?.[1]).format(type == 1 ? "yyyyMM" : "yyyy-MM-dd");
    } else {
      queryStartTime = value?.[0];
      queryEndTime = value?.[1];
    }
    let [queryStartName, queryEndName] = ["queryStartTime", "queryEndTime"];
    this[queryStartName] = queryStartTime;
    this[queryEndName] = queryEndTime;
  }
  handleYear (key, value) {
    let year = "year"
    this[year] = value?.[0];
  }

  handleAllLevels (key, value, filter) {
    let [inHome, status] = filter.keys || [key, "status"];
    this[inHome] = value[0];
    this[status] = value[1];
  }
  handleSign (key, value, filter) {
    let [
      signExceptionStatus,
      receiptAttachmentStatus,
      receiptReplenishStatus,
      receiptReviewStatus,
      receiptLoseStatus
    ] = filter.keys || [
      "signExceptionStatus",
      `${key}AttachmentStatus`,
      `${key}ReplenishStatus`,
      `${key}ReviewStatus`,
      `${key}LoseStatus`
    ];
    let person = new Map([
      [1, "signExceptionStatus"],
      [2, "receiptAttachmentStatus"],
      [3, "receiptReplenishStatus"],
      [4, "receiptReviewStatus"],
      [5, "receiptLoseStatus"]
    ]);
    this[person.get(value)] = 1;
  }

  handleSigns (key, value, filter) {
    const { keys = ["signExceptionStatus", `${key}AttachmentStatus`, `${key}LoseStatus`] } = filter;
    const { signExceptionStatus, receiptAttachmentStatus, receiptLoseStatus } = {    // eslint-disable-line
      signExceptionStatus: 1,
      receiptAttachmentStatus: 2,
      receiptLoseStatus: 3
    };
    this[keys[value - 1]] = 1;
  }

}

class TableRecord {
  constructor(record, columns) {
    Object.assign(this, record);
    columns.forEach((column) => {
      let { name, alias, reader } = column;
      if (alias) {
        this[alias] = record[alias];
      }
      if (reader) {
        this[name] = reader(record);
      } else {
        this[name] = record[name];
      }
    });
  }
}


const MUTATION_TYPES = {
  FILTERS: "FILTERS",
  COLUMNS: "COLUMNS",
  ACTIONS: "ACTIONS",
  RECORDS: "RECORDS",
  LOCALIZE: "LOCALIZE",
  // LOADING: 'LOADING',
  TABLOAD: "TABLOAD",
  // COMPONENTNAME: 'COMPONENTNAME', orderTableTotal
  FORMCONTAINERINFO: "FORMCONTAINERINFO",
  ORDER_TABLE_TOTAL: "ORDER_TABLE_TOTAL",
  PAGE: "PAGE",
  VIEW: "VIEW",
  FIRST_NEW_RECORDS_SEARCH: 'FIRST_NEW_RECORDS_SEARCH',
  UPDATE_GETTER_FLAG: 'UPDATE_GETTER_FLAG',
  ADVANCE_NEW_RECORDS_SEARCH: 'ADVANCE_NEW_RECORDS_SEARCH',
  CLEAR_FIRST_NEW_RECORD_SEARCH: 'CLEAR_FIRST_NEW_RECORD_SEARCH'
  // PAGE_TOTAL: 'PAGE_TOTAL',
};

const state = {
  filters: null,
  columns: null,
  records: [],
  summary: {},
  pageTotal: {},
  page: {},
  actions: [],
  total: 0,
  localize: {},
  // loading: true,
  // componentName: null,
  viewVisible: false,
  viewContext: null,
  // recordsearch: null,
  firstNewRecordSearch: {},
  advanceNewRecordSearch: {},
  updateGetterFlag: null
};

const getters = {
  getMenuFirstRecordSearch: (state, getters) => (userId, menuId) => {
    console.log('Should update getter?', state.updateGetterFlag);
    if (state.updateGetterFlag) {
      const updatedRecordSearch = getters.getMenuFirstRecordSearch(userId, menuId);
      return updatedRecordSearch;
    } else {
      return state.firstNewRecordSearch?.[userId]?.[menuId] || {};
    }
  },
  getMenuAdvanceRecordSearch: (state, getters) => (userId, menuId) => {
    console.log('Should update getter?', state.updateGetterFlag);
    if (state.updateGetterFlag) {
      // 强制触发计算属性的重新计算
      const updatedRecordSearch = getters.getMenuAdvanceRecordSearch(userId, menuId);
      return updatedRecordSearch;
    } else {
      return state.advanceNewRecordSearch?.[userId]?.[menuId] || {};
    }
  },
};

const mutations = {
  [MUTATION_TYPES.LOCALIZE] (state, localize = {}) {
    state.localize = localize || {};
    state.summary = localize?.summary || {}
    state.search = localize?.search || {}
  },
  [MUTATION_TYPES.FILTERS] (state, filters = []) {
    state.filters = new TableFilters(filters, state.search);
  },
  [MUTATION_TYPES.COLUMNS] (state, columns = []) {
    state.columns = new TableColumns(columns);
  },
  [MUTATION_TYPES.ACTIONS] (state, actions = []) {
    state.actions = actions || [];
  },
  [MUTATION_TYPES.RECORDS] (state, { records, total }) {
    state.records = [];
    state.records = records?.map((item) => {
      return new TableRecord(item, state.columns);
    });
    state.total = total;
  },
  [MUTATION_TYPES.PAGE] (state, { page, pageTotal }) {
    state.records = [];
    state.records = page?.records?.map((item) => {
      return new TableRecord(item, state.columns);
    });
    state.pageTotal = pageTotal;
    state.total = page?.total;
  },
  [MUTATION_TYPES.VIEW] (state, viewContext) {
    state.viewContext = viewContext;
    state.viewVisible = !!viewContext;
  },
  [MUTATION_TYPES.CLEAR_FIRST_NEW_RECORD_SEARCH] (state, userId) {
    if (state.firstNewRecordSearch[userId]) {
      state.firstNewRecordSearch[userId] = {};
    }
    if (state.advanceNewRecordSearch[userId]) {
      state.advanceNewRecordSearch[userId] = {};
    }
    state.records = []
    state.columns = []
  },
  [MUTATION_TYPES.FIRST_NEW_RECORDS_SEARCH] (state, { userId, menuId, firstNewRecordSearch = {} }) {
    if (!state.firstNewRecordSearch[userId]) {
      state.firstNewRecordSearch[userId] = {};
    }
    state.firstNewRecordSearch[userId][menuId] = firstNewRecordSearch;
  },
  [MUTATION_TYPES.ADVANCE_NEW_RECORDS_SEARCH] (state, { userId, menuId, advanceNewRecordSearch = {} }) {
    if (!state.advanceNewRecordSearch[userId]) {
      state.advanceNewRecordSearch[userId] = {};
    }
    state.advanceNewRecordSearch[userId][menuId] = advanceNewRecordSearch;
  },
  // 新增的mutation，用于标记需要重新计算getter
  [MUTATION_TYPES.UPDATE_GETTER_FLAG] (state, flag) {
    state.updateGetterFlag = flag;
  },
  // [MUTATION_TYPES.LOADING] (state, loading) {
  //   state.loading = loading;
  // }
};

const actions = {
  localize ({ commit }, localize) {
    commit(MUTATION_TYPES.LOCALIZE, localize);
  },
  initialize ({ commit }, { filters, columns, actions, localize }) {
    commit(MUTATION_TYPES.LOCALIZE, localize);
    commit(MUTATION_TYPES.FILTERS, filters);
    commit(MUTATION_TYPES.COLUMNS, columns);
    commit(MUTATION_TYPES.ACTIONS, actions);
  },
  async search ({ commit, state }, { userId, menuId, data }) {
    let url = state.filters.search?.url;
    if (!url) {
      console.log("没有设置搜索地址", JSON.stringify(state.filters.search));
      Vue.prototype.$message({ type: "error", message: "没有设置搜索地址" });
      return;
    }
    const reorder = data?.sort || state.firstNewRecordSearch?.[userId]?.[menuId]?.sort

    const filterData = {
      ...state.firstNewRecordSearch?.[userId]?.[menuId],
      ...state.advanceNewRecordSearch?.[userId]?.[menuId],
      ...data, sort: reorder
    }
    const resolver = new DataResolver(filterData, state.filters);
    console.log("列表data: ", data, JSON.stringify(resolver));

    let response = await table.search(url, resolver);
    if (response?.code === 0) {
      commit(MUTATION_TYPES.RECORDS, response.data);
      this.loading = false
      if (response.data?.page && response.data?.page instanceof Object) {
        commit(MUTATION_TYPES.PAGE, response.data);
        // commit(MUTATION_TYPES.PAGE_TOTAL, response.data?.pageTotal)
      }
    }
  },
  async recordFirstNewFilters ({ commit, state }, { userId, menuId, data }) {
    const transformFilters = transformFilterData(data, state.filters)
    // 更新updateGetterFlag为true，表示需要重新计算getter
    commit(MUTATION_TYPES.UPDATE_GETTER_FLAG, true);
    commit(MUTATION_TYPES.FIRST_NEW_RECORDS_SEARCH, { userId, menuId, firstNewRecordSearch: transformFilters });
    // 更新完tags后，将updateGetterFlag重新设置为false，停止重新计算getter
    commit(MUTATION_TYPES.UPDATE_GETTER_FLAG, false);
  },
  async recordAdvanceNewFilters ({ commit, state }, { userId, menuId, data }) {
    const transformFilters = transformFilterData(data, state.filters)
    // 更新updateGetterFlag为true，表示需要重新计算getter
    commit(MUTATION_TYPES.UPDATE_GETTER_FLAG, true);
    commit(MUTATION_TYPES.ADVANCE_NEW_RECORDS_SEARCH, { userId, menuId, advanceNewRecordSearch: transformFilters });
    // 更新完tags后，将updateGetterFlag重新设置为false，停止重新计算getter
    commit(MUTATION_TYPES.UPDATE_GETTER_FLAG, false);
  },
  async clearFirstNewRecordSearch ({ commit }, userId) {
    commit(MUTATION_TYPES.CLEAR_FIRST_NEW_RECORD_SEARCH, userId);
    commit(MUTATION_TYPES.UPDATE_GETTER_FLAG, false);
  },
};

export default {
  strict: debug,
  namespaced: true,
  state,
  getters,
  mutations,
  actions
};
